package com.holyant.goods.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
//import com.ruoyi.common.file.service.ISysFileService;
//import com.holyant.bac.api.dto.BaseFileDto;
import com.ruoyi.common.core.domain.ApiRes;
import com.ruoyi.common.core.enums.CloseFlagEnum;
import com.ruoyi.common.core.enums.DelFlagEnum;
import com.ruoyi.common.core.exception.CustomException;
import com.ruoyi.common.utils.AssertUtils;
import com.ruoyi.common.utils.ChineseCharToEn;
import com.ruoyi.common.utils.SnowflakeIdWorkerUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.holyant.goods.constants.CacheConstants;
import com.holyant.goods.dto.GdsBrandCatenaDto;
import com.holyant.goods.dto.GdsBrandDto;
import com.holyant.goods.dto.GdsBrandImportDto;
import com.holyant.goods.dto.query.GdsBrandCatenaQueryDto;
import com.holyant.goods.dto.query.GdsBrandQueryDto;
import com.holyant.goods.entity.GdsBrandEntity;
import com.holyant.goods.mapper.GdsBrandMapper;
//import com.holyant.goods.service.IGdsBrandCatenaService; //TODO holyant
import com.holyant.goods.service.IGdsBrandService;
//import com.holyant.goods.service.IGdsGoodsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.validation.Validator;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 商品品牌Service业务层处理
 * 
 * @author fkmalls
 * @date 2021-03-31
 */
@Slf4j
@Service
public class GdsBrandServiceImpl implements IGdsBrandService {
    @Autowired
    private GdsBrandMapper gdsBrandMapper;

    @Autowired
    private Validator validator;
    
//    @Autowired
//    private IGdsGoodsService gdsGoodsService;

//    @Autowired
//    private RemoteFileService remoteFileService;

    @Autowired
    private RedisService redisService;
//    @Autowired
//    private IGdsBrandCatenaService brandCatenaService;

    /**
     * 查询商品品牌
     * 
     * @param id 商品品牌ID
     * @return 商品品牌Dto
     */
    @Override
    public GdsBrandDto selectGdsBrandById(Long id)
    {
        GdsBrandDto gdsBrandDto = new GdsBrandDto();
        GdsBrandEntity gdsBrandEntity = gdsBrandMapper.selectById(id);
        BeanUtils.copyBeanProp(gdsBrandEntity,gdsBrandDto);
//        // 查询商品的所有图片信息
//        ApiRes<List<BaseFileDto>> res = remoteFileService.getFilesByBs(null,id);
//        if (res.succeed()){
//            gdsBrandDto.setImages(CollectionUtils.isEmpty(res.getData())?Collections.emptyList():res.getData());
//        } else {
//            throw new CustomException("图片加载失败:" + res.getMsg());
//        }
        return gdsBrandDto;
    }

    /**
     * 查询商品品牌列表
     * 
     * @param gdsBrandQueryDto 商品品牌
     * @return 商品品牌Dto
     */
    @Override
    public List<GdsBrandDto> selectGdsBrandList(GdsBrandQueryDto gdsBrandQueryDto)
    {
        return gdsBrandMapper.selectGdsBrandList(gdsBrandQueryDto);
    }

    /**
     * 查询品牌系列
     * @param gdsBrandCatenaQueryDto
     * @return
     */
    @Override
    public List<GdsBrandCatenaDto> selectGdsBrandListForCatena(GdsBrandCatenaQueryDto gdsBrandCatenaQueryDto) {
        return gdsBrandMapper.selectGdsBrandListForCatena(gdsBrandCatenaQueryDto);
    }

    /**
     * 新增商品品牌
     * 
     * @param gdsBrandDto 商品品牌
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long insertGdsBrand(GdsBrandDto gdsBrandDto)
    {
        GdsBrandEntity gdsBrandEntity = new GdsBrandEntity();
        BeanUtils.copyBeanProp(gdsBrandDto,gdsBrandEntity);
        gdsBrandEntity.setId(SnowflakeIdWorkerUtils.getId());
        gdsBrandEntity.setVer(SnowflakeIdWorkerUtils.getId());
        gdsBrandEntity.setEName(gdsBrandDto.getEName());
        if(this.existByName(null,gdsBrandEntity.getName())){
            throw new CustomException("品牌名称:[" + gdsBrandEntity.getName() + "] 重复");
        }
        if(this.existByCode(null,gdsBrandEntity.getCode())){
            throw new CustomException("品牌编码:[" + gdsBrandEntity.getCode() + "] 重复");
        }
        //品牌编码 限4位字母,默认为品牌的中文名称的前四个字的拼音首字母
        String code = getCode(ChineseCharToEn.getAllFirstLetter(gdsBrandDto.getName()));
        gdsBrandEntity.setCode(code);
        // logo 为空直接新增
        if (CollectionUtils.isEmpty(gdsBrandDto.getImages())){
            gdsBrandEntity.setUniformCode("" + getNextSerNum());
            if(1 != gdsBrandMapper.insert(gdsBrandEntity)){
                throw new CustomException("新增品牌失败");
            }
            return gdsBrandEntity.getId();
        }
//        // 保存一下图片
//        saveImages(gdsBrandDto.getImages(),gdsBrandEntity.getId());
//        // 如果有图片就设置一下主图
//        if (gdsBrandDto!=null && gdsBrandDto.getImages() != null && gdsBrandDto.getImages().size()!=0) {
//            gdsBrandEntity.setImgUrl(gdsBrandDto.getImages().get(0).getUrl());
//        }
        gdsBrandEntity.setUniformCode("" + getNextSerNum());
        if(1 != gdsBrandMapper.insert(gdsBrandEntity)){
            throw new CustomException("新增品牌失败");
        }
        return gdsBrandEntity.getId();
    }
    
    private String getCode(String code){
        if (code.length()>=4){
            return code.substring(0,4).toUpperCase();
        }else {
            int length = code.length();
            StringBuilder sb = new StringBuilder();
            for (int i=0; i<4-length; i++){
                sb.append("0");
            }
            return String.format("%s%s",code.toUpperCase(),sb);
        }
        
    }

    /**
     * 修改商品品牌
     * 
     * @param gdsBrandDto 商品品牌
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateGdsBrand(GdsBrandDto gdsBrandDto)
    {
        GdsBrandEntity gdsBrandEntityOrgin = gdsBrandMapper.selectById(gdsBrandDto.getId());
        GdsBrandEntity gdsBrandEntity = new GdsBrandEntity();
        BeanUtils.copyBeanProp(gdsBrandDto,gdsBrandEntity);
//        if(gdsGoodsService.countByBrandId(gdsBrandDto.getId())>0){ //TODO holyant
//            throw new CustomException("此品牌已存在商品信息,无法修改");
//        }
        gdsBrandEntity.setVer(SnowflakeIdWorkerUtils.getId());
        if(this.existByName(gdsBrandEntity.getId(),gdsBrandEntity.getName())){
            throw new CustomException("品牌名称:[" + gdsBrandEntity.getName() + "] 重复");
        }
        if(this.existByCode(gdsBrandEntity.getId(),gdsBrandEntity.getCode())){
            throw new CustomException("品牌编码:[" + gdsBrandEntity.getCode() + "] 重复");
        }
        // logo 为空直接更新其他字段
        if (CollectionUtils.isEmpty(gdsBrandDto.getImages())){
            if (gdsBrandMapper.update(gdsBrandEntity, new UpdateWrapper<GdsBrandEntity>()
                    .eq("id", gdsBrandDto.getId()).eq("ver", gdsBrandEntityOrgin.getVer())) != 1) {
                throw new CustomException( gdsBrandEntityOrgin.getName() + "修改失败,数据已被别人修改！");
            }
            return 1;
        }
        // 保存一下图片
//        saveImages(gdsBrandDto.getImages(),gdsBrandDto.getId());
        // 如果有图片就设置一下主图
//        if (gdsBrandDto!=null && gdsBrandDto.getImages() != null && gdsBrandDto.getImages().size()!=0) {
//            gdsBrandEntity.setImgUrl(gdsBrandDto.getImages().get(0).getUrl());
//        }

        if (gdsBrandMapper.update(gdsBrandEntity, new UpdateWrapper<GdsBrandEntity>()
                .eq("id", gdsBrandDto.getId()).eq("ver", gdsBrandEntityOrgin.getVer())) != 1) {
            throw new CustomException( gdsBrandEntityOrgin.getName() + "修改失败,数据已被别人修改！");
        }
        return 1;
    }

    /**
     * 临时方法
     */
    private void updateBrandUniformCode(GdsBrandDto gdsBrandDto) {
        GdsBrandEntity gdsBrandEntityOrgin = gdsBrandMapper.selectById(gdsBrandDto.getId());
        GdsBrandEntity gdsBrandEntity = new GdsBrandEntity();
        gdsBrandEntity.setVer(SnowflakeIdWorkerUtils.getId());
        gdsBrandEntity.setUniformCode(gdsBrandDto.getUniformCode());

        if (gdsBrandMapper.update(gdsBrandEntity, new UpdateWrapper<GdsBrandEntity>()
                .eq("id", gdsBrandDto.getId()).eq("ver", gdsBrandEntityOrgin.getVer())) != 1) {
            throw new CustomException( gdsBrandEntityOrgin.getName() + "修改失败,数据已被别人修改！");
        }
    }

    /**
     * 批量删除商品品牌
     * 
     * @param ids 需要删除的商品品牌ID
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteGdsBrandByIds(Long[] ids)
    {
        int rows = 0;
        for (Long id : ids){
            rows += this.deleteGdsBrandById(id);
        }
        return rows;
    }

    /**
     * 删除商品品牌信息
     * 
     * @param id 商品品牌ID
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteGdsBrandById(Long id)
    
    {
//        if(gdsGoodsService.countByBrandId(id)>0){ //TODO holyant
//            throw new CustomException("此品牌已存在商品信息,无法删除");
//        }
        if(1 != gdsBrandMapper.deleteById(id)){
            throw new CustomException("删除品牌信息失败");
        }
//        //同步维护品牌系列
//        brandCatenaService.deleteGdsBrandCatenaItemByParentId(id);
        return 1;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int close(Long id) {
        GdsBrandEntity gdsBrandEntityOrgin = gdsBrandMapper.selectById(id);
        if(!CloseFlagEnum.NO_CLOSE.getCode().equals(gdsBrandEntityOrgin.getCloseFlag())){
            throw new CustomException("此品牌已经停用!");
        }
        GdsBrandEntity gdsBrandEntity = new GdsBrandEntity();
        BeanUtils.copyBeanProp(gdsBrandEntityOrgin,gdsBrandEntity);
        gdsBrandEntity.setVer(SnowflakeIdWorkerUtils.getId());
        gdsBrandEntity.setCloseFlag(CloseFlagEnum.CLOSED.getCode());
        if (gdsBrandMapper.update(gdsBrandEntity, new UpdateWrapper<GdsBrandEntity>()
                .eq("id", id).eq("ver", gdsBrandEntityOrgin.getVer())) != 1) {
            throw new CustomException( gdsBrandEntityOrgin.getName() + "操作失败,数据已被别人修改！");
        }
//        //同步品牌系列
//        brandCatenaService.updateBrandCatenaByCloseBrand(gdsBrandEntity);
        return 1;
    }
    @Override
    public int updateBrandCode(){
        GdsBrandQueryDto gdsBrandQueryDto = new GdsBrandQueryDto();
        List<GdsBrandDto> gdsBrandDtos = gdsBrandMapper.selectGdsBrandList(gdsBrandQueryDto);
        for (GdsBrandDto g:gdsBrandDtos) {
            if(Objects.isNull(g.getCode()) || g.getCode().equals("")){
                g.setCode(getCode(ChineseCharToEn.getAllFirstLetter(g.getName())));
                GdsBrandDto gdsBrandDtoOrgin = selectGdsBrandById(g.getId());
                GdsBrandEntity gdsBrandEntity = new GdsBrandEntity();
                BeanUtils.copyProperties(gdsBrandDtoOrgin,gdsBrandEntity);
                gdsBrandEntity.setCode(g.getCode());
                if (gdsBrandMapper.update(gdsBrandEntity, new UpdateWrapper<GdsBrandEntity>()
                        .eq("id", g.getId()).eq("ver", gdsBrandDtoOrgin.getVer())) != 1) {
                    throw new CustomException( g.getName() + "操作失败,数据已被别人修改！");
                }
            }
        }
        return 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int initBrandUniformCode() {
        List<GdsBrandDto> gdsBrandDtos = selectGdsBrandList(new GdsBrandQueryDto());
        int serialNum = 0;
        for (GdsBrandDto gdsBrandDto : gdsBrandDtos) {
            gdsBrandDto.setUniformCode(String.format("%02d", ++serialNum));
            updateBrandUniformCode(gdsBrandDto);
        }
        return gdsBrandDtos.size();
    }

    /**
     * 名称是否存在
     * @param name
     * @return
     */
    public boolean existByName(Long id, String name) {
        QueryWrapper<GdsBrandEntity> queryWrapper = new QueryWrapper<GdsBrandEntity>();
        if((id != null)){
            queryWrapper.notIn("id",id);
        }
        queryWrapper.eq("name",name);
        return gdsBrandMapper.selectCount(queryWrapper) > 0;
    }
    /**
     * 编码是否存在
     * @param code
     * @return
     */
    public boolean existByCode(Long id, String code) {
        QueryWrapper<GdsBrandEntity> queryWrapper = new QueryWrapper<GdsBrandEntity>();
        if((id != null)){
            queryWrapper.notIn("id",id);
        }
        queryWrapper.eq("code",code);
        return gdsBrandMapper.selectCount(queryWrapper) > 0;
    }

//    /**
//     * 保存商品的图片
//     * @param fileList 文件信息列表
//     * @param id 商品id
//     * @return
//     */
//    private void saveImages(List<BaseFileDto> fileList, Long id) {
//        // 避免为空
//        if (fileList == null) {
//            fileList = Collections.EMPTY_LIST;
//        }
//        List<Long> ids = fileList.stream().map(dto -> {
//            return dto.getId();
//        }).collect(Collectors.toList());
//        ApiRes<Integer> res = remoteFileService.updateFileBelong(ids,null,id,true);
//        if (fileList.size() != res.getData()) {
//            throw new CustomException("商品图片异常");
//        }
//    }

    /**
     * 获取下一个最大流水号
     * * @param goodsId
     *
     * @return
     */
    private Integer getNextSerNum() {
        Integer maxSerNum = redisService.getCacheObject(CacheConstants.BRAND_UNIFORMCODE_MAX_SERIAL_NUM_CACHE_KEY);
        if (Objects.isNull(maxSerNum)) {
            maxSerNum = gdsBrandMapper.getMaxUniformCodeSerNum();
        }
        maxSerNum = Objects.isNull(maxSerNum) ? 1 : ++maxSerNum;
        if (maxSerNum > 999) {
            throw new CustomException("流水号已超最大值：999，请联系工作人员处理");
        }
        redisService.setCacheObject(CacheConstants.BRAND_UNIFORMCODE_MAX_SERIAL_NUM_CACHE_KEY, maxSerNum);
        return maxSerNum;
    }

    private void deleteMaxSerNumCache() {
        redisService.deleteObject(CacheConstants.BRAND_UNIFORMCODE_MAX_SERIAL_NUM_CACHE_KEY);
    }

    @Override
    public GdsBrandDto findByName(String name) {
        GdsBrandEntity gdsBrandEntity = new LambdaQueryChainWrapper<>(gdsBrandMapper)
                .eq(GdsBrandEntity::getName, name)
                .eq(GdsBrandEntity::getDelFlag, DelFlagEnum.OK.getCode())
                .one();
        if (ObjectUtil.isNull(gdsBrandEntity)){
            return null;
        }
        GdsBrandDto gdsBrandDto = new GdsBrandDto();
        BeanUtils.copyBeanProp(gdsBrandEntity,gdsBrandDto);
        return gdsBrandDto;
    }


    /**
     * @param gdsBrandImportDtos
     * @return
     */
    @Override
    @Transactional(rollbackFor=Exception.class)
    public ApiRes<Map<String, List<GdsBrandImportDto>>> importData(List<GdsBrandImportDto> gdsBrandImportDtos) {
        HashMap<String, List<GdsBrandImportDto>> hashMap = new HashMap<>();
        int failureNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        //保存订单导入的列表
        Map<String, List<GdsBrandImportDto>> insertBrands = new HashMap<>();
        //保存订单更新的列表
        Map<String, List<GdsBrandImportDto>> updateBrands = new HashMap<>();
        if (CollectionUtils.isEmpty(gdsBrandImportDtos)){
            return ApiRes.ok(null, "导入失败品牌数据为空!!!");
        }

        // 校验是否存在重复数据
        checkDuplicateBrandName(gdsBrandImportDtos);


        // 遍历
        for (GdsBrandImportDto brandImportDto : gdsBrandImportDtos) {
            try {
                checkBrandImportDto(brandImportDto);
                //查询品牌是否存在
                GdsBrandDto brandDto = findByName(brandImportDto.getBrandName());
                if (Objects.nonNull(brandDto)){

                    List<GdsBrandImportDto> brandImportDtos = updateBrands.get(brandImportDto.getBrandName());
                    if (Objects.isNull(brandImportDtos)) {
                        brandImportDtos = new ArrayList<>();
                        updateBrands.put(brandDto.getName(), brandImportDtos);
                    }
                    brandImportDtos.add(brandImportDto);
                }else{
                    List<GdsBrandImportDto> insertBrandImportDtos = insertBrands.get(brandImportDto.getBrandName());
                    if (Objects.isNull(insertBrandImportDtos)) {
                        insertBrandImportDtos = new ArrayList<>();
                        insertBrands.put(brandImportDto.getBrandName(), insertBrandImportDtos);
                    }
                    insertBrandImportDtos.add(brandImportDto);
                }
            }catch (Exception e){
                failureNum++;
                String msg = "<br/>" + failureNum + "、商品品牌 " + brandImportDto.getBrandName() + " 导入解析失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }

        List<GdsBrandImportDto> updateLists = new ArrayList<>();
        Iterator<Map.Entry<String, List<GdsBrandImportDto>>> updateIterator = updateBrands.entrySet().iterator();
        while (updateIterator.hasNext()) {
            Map.Entry<String, List<GdsBrandImportDto>> updateBrandsEntry = updateIterator.next();
            List<GdsBrandImportDto> orderGroup = updateBrands.get(updateBrandsEntry.getKey());
            GdsBrandImportDto brandImportDto = orderGroup.get(0);
            GdsBrandDto brandDto = findByName(brandImportDto.getBrandName());
//            if(gdsGoodsService.countByBrandId(brandDto.getId())>0){
//                failureMsg.append("<br/>" + String.format("此品牌:%s已存在商品信息,无法修改",brandDto.getName()));
//                continue;
//            }
            updateLists.add(brandImportDto);
        }
        hashMap.put("update",updateLists);


        List<GdsBrandImportDto> insertLists = new ArrayList<>();
        Iterator<Map.Entry<String, List<GdsBrandImportDto>>> insertIterator = insertBrands.entrySet().iterator();
        while (insertIterator.hasNext()) {
            Map.Entry<String, List<GdsBrandImportDto>> brandImportDtoEntry = insertIterator.next();
            List<GdsBrandImportDto> orderGroup = insertBrands.get(brandImportDtoEntry.getKey());
            insertLists.add(orderGroup.get(0));
        }
        hashMap.put("insert",insertLists);

        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new CustomException(failureMsg.toString());
        }


        if (StringUtils.isNotEmpty(failureMsg.toString())){
            return ApiRes.ok(null,failureMsg.toString());
        }else{
            return ApiRes.ok(hashMap,null);
        }
    }

    private void checkDuplicateBrandName(List<GdsBrandImportDto> gdsBrandImportDtos) {
        StringBuilder duplicateMsg = new StringBuilder();
        Set<String> uniqueSet = new HashSet<>();
        Set<String> duplicateSet = new HashSet<>();

        for (GdsBrandImportDto brandImportDto : gdsBrandImportDtos) {
            if (!uniqueSet.add(brandImportDto.getBrandName())) {
                duplicateSet.add(brandImportDto.getBrandName());
            }
        }

        if (!duplicateSet.isEmpty()) {
            for (String brandName : duplicateSet) {
                String msg = "<br/>"  + "、商品品牌: " + brandName + ",存在重复数据,";
                duplicateMsg.append(msg);
            }
            duplicateMsg.insert(0,"存在以下重复数据无法导入");
            throw new CustomException(duplicateMsg.toString());
        }

    }


    @Override
    @Transactional(rollbackFor=Exception.class)
    public int importDataUpdate(List<GdsBrandImportDto> gdsBrandImportDtos) {
        AssertUtils.trueError(CollectionUtils.isEmpty(gdsBrandImportDtos),"数据为空,无法更新导入数据!!!");
        for (GdsBrandImportDto brandImportDto : gdsBrandImportDtos) {
            GdsBrandDto brandDto = findByName(brandImportDto.getBrandName());
            if (Objects.isNull(brandDto)){
                this.insertGdsBrand(GdsBrandImportDto.convertGdsBrandDto(brandImportDto));
            }else{
//                if(gdsGoodsService.countByBrandId(brandDto.getId())>0){
//                    throw new CustomException(String.format("此品牌:%s已存在商品信息,无法修改",brandDto.getName()));
//                }
                GdsBrandEntity gdsBrandEntity = new GdsBrandEntity();
                BeanUtils.copyProperties(GdsBrandImportDto.convertGdsBrandDto(brandImportDto),gdsBrandEntity);
                if (gdsBrandMapper.update(gdsBrandEntity, new UpdateWrapper<GdsBrandEntity>()
                        .eq("id", brandDto.getId()).eq("ver", brandDto.getVer())) != 1) {
                    throw new CustomException( brandDto.getName() + "修改失败,数据已被别人修改！");
                }
            }
        }
        return gdsBrandImportDtos.size();
    }

    private void checkBrandImportDto(GdsBrandImportDto brandImportDto) {
        AssertUtils.trueError(StringUtils.isEmpty(brandImportDto.getBrandName()),"品牌名称不能为空!!!");
        AssertUtils.trueError(StringUtils.isEmpty(brandImportDto.getBrandEnName()),"品牌英文名称不能为空!!!");
        AssertUtils.trueError(StringUtils.isEmpty(brandImportDto.getBrandNation()),"品牌国家不能为空!!!");
    }
}
